package com.ruijie.acl.task.config;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.util.Assert;

import com.ruijie.acl.task.TaskAclDomain;
import com.ruijie.acl.task.TaskAclUtil;
import com.ruijie.acl.task.model.AccessGroupInfo;
import com.ruijie.acl.task.model.AceInfo;
import com.ruijie.acl.task.model.AclInterfaceInfo;
import com.ruijie.acl.task.model.TimeInfo;
import com.ruijie.acl.task.model.TimeRangeInfo;
import com.ruijie.acl.type.AceTypeEnum;
import com.ruijie.acl.type.AclPlanTypeEnum;
import com.ruijie.acl.utils.AclConfigUtil;
import com.ruijie.acl.utils.AclUtil;
import com.ruijie.batch.core.factory.SpringConfigAware;
import com.ruijie.batch.plan.PlanParameters;
import com.ruijie.batch.task.ItemProcessResult;
import com.ruijie.emp.batch.task.AbstractDeviceTasklet;
import com.ruijie.emp.device.Device;
import com.ruijie.emp.event.support.EventPublisher;
import com.ruijie.emp.system.service.TelnetTemplateService;
import com.ruijie.emp.task.EMPTaskDomain;
import com.ruijie.emp.task.util.TaskUtil;
import com.ruijie.foundation.adapter.Adapter;
import com.ruijie.foundation.adapter.AdapterDomain;
import com.ruijie.foundation.adapter.parameter.ParameterExecutor;
import com.ruijie.foundation.adapter.utils.Dom4jUtil;
import com.ruijie.foundation.exception.BusinessException;
import com.ruijie.network.model.TelnetParameter;

/**
 * 
 * <p>
 * Title: TaskConfigAclDevice
 * </p>
 * <p>
 * Description: 配置ACL设备的信息
 * </p>
 * <p>
 * Copyright: Copyright (c) 2009
 * </p>
 * <p>
 * Company: Ruijie Co., Ltd.
 * </p>
 * <p>
 * Create Time: 2009-9-17
 * </p>
 * 
 * @author ASAI
 *         <p>
 *         Update Time:
 *         </p>
 *         <p>
 *         Updater:
 *         </p>
 *         <p>
 *         Update Comments:
 *         </p>
 */
public class TaskConfigAclDevice extends AbstractDeviceTasklet implements SpringConfigAware {
	private Log logger = LogFactory.getLog(TaskConfigAclDevice.class);

	protected EventPublisher eventPublisher;

	protected TelnetTemplateService service;

	private String cmdErrorStr = "";
	private String cmdDoneFlag = "";
	private String cmdSuccFlag = "";

	private String cmdConfigEnd = "";
	private String cmdEnd = "";

	private String cmdLine = "";
	private Device dealDevice = null;

	// 错误信息
	private String[] errs = null;

	public TelnetTemplateService getService() {
		return service;
	}

	public void setService(TelnetTemplateService service) {
		this.service = service;
	}

	@SuppressWarnings("unchecked")
	public ItemProcessResult processItem(Object item, PlanParameters parameters) {
		ItemProcessResult result = new ItemProcessResult();

		Assert.notNull(item, "item is null");

		Device device = (Device) item;
		// 取得设备的Telnet模板是否成功
		if (device.getTelnetTemplate() == null) {
			if (service != null) {
				logger.warn("device.getTelnetTemplate() is null.");
				device.setTelnetTemplate(service.getDefault());
			}
			if (device.getTelnetTemplate() == null) {
				result.setSuccess(false);
				result.setException(new BusinessException(
						EMPTaskDomain.EMP_TASK_PARA_TELNETTEMPLOST));
				return result;
			}
		}

		TelnetParameter telnetParameter = TaskUtil.loadTelnetParameter(device, true);

		ParameterExecutor pe = new ParameterExecutor();
		HashMap para = new HashMap(parameters.getParameters());

		String conn = TaskUtil.tranTelnetConnStr(telnetParameter);

		pe.setupInterfaceInfo(TaskUtil.getDeviceSimpleCode(device, "SwitchTelnet"), "");
		pe.setupTargetSystem("", "", "SwitchTelnet", device.getAdminIp(), ""
				+ telnetParameter.getPort(), "", "", conn, telnetParameter.getUser(),
				telnetParameter.getPassword(), "false");
		pe.setupProtocol("", "", "SwitchTelnet", "", "" + telnetParameter.getTimeout(), "", "", "",
				"", "", "0");

		String cmdPrompt = telnetParameter.isNeedSuPassword() //
		? telnetParameter.getSuPrompt()
				: telnetParameter.getPrompt();

		// 错误信息
		String[] errs1 = {
				"Invalid input detected", //
				"Not eligible for secure port", //
				"Unknown command",//
				"Incomplete command", //
				"Unrecognized command", //
				"Incomplete command", //
				"Bad ACL",//
				"Acl Mode Not Match",//
				"Cannot delete given timerange mode currently",//		
				"Input is invalid", //
				"for the entry is existed", "Name is too long", "not supported by device",
				"date or time is illegal", "Specified ACL not created",
				"Acl is referred to secu-channel",
				"Please disable dot1x port-control before deleting acl",
				"Conflicting ACEs in one ACL", "Duplicated ACEs in police map",
				"Access-list type conflicts with prior definition", "Another acl has attached",
				"Operation fail" };

		errs = errs1;

		cmdErrorStr = TaskUtil.array2str(errs, "|");
		cmdDoneFlag = cmdPrompt;
		cmdSuccFlag = cmdPrompt;

		cmdConfigEnd = "config\\)" + cmdPrompt.charAt(cmdPrompt.length() - 1);
		cmdEnd = "\\)" + cmdPrompt.charAt(cmdPrompt.length() - 1);

		cmdLine = this.getLineString((Device) item);

		dealDevice = ((Device) item);

		// 取得处理标志
		String dealFlag = parameters.getParameter("dealFlag");

		// 如果没有输入处理标志，或者不是为修改"modify"、删除"delete"时，设置为添加"add"
		if (dealFlag == null || dealFlag.trim().length() == 0) {
			dealFlag = "add";
		}

		// [start] 如果为添加
		if (dealFlag.equals("add")) {
			// [start] Time Range
			if (parameters.getParameters().containsKey("timerangeInfoList")) {

				// 开始设置命令
				pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd,
						cmdConfigEnd, null));

				List<TimeRangeInfo> timeRangeInfoList = (List<TimeRangeInfo>) parameters
						.getParameters().get("timerangeInfoList");

				this.addTimeRangeInfos(timeRangeInfoList, pe, para, (Device) item);

				// 
				pe.addCommand(pe.buildCommandOperate("end", cmdErrorStr + cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
				pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
			}
			// [end] Time Range

			// [start] Access List
			if (parameters.getParameters().containsKey("accessGroupInfoList")) {

				// 开始设置命令
				pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd,
						cmdConfigEnd, null));

				List<AccessGroupInfo> accessGroupInfoList = (List<AccessGroupInfo>) parameters
						.getParameters().get("accessGroupInfoList");

				this.addAccessGroupInfos(accessGroupInfoList, pe, para);
				// 
				pe.addCommand(pe.buildCommandOperate("end", cmdErrorStr + cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
				pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
			}
			// [end]

			// [start] Acl Interface
			if (parameters.getParameters().containsKey("aclInterfaceInfoList")) {
				// 开始设置命令
				pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd,
						cmdConfigEnd, null));

				List<AclInterfaceInfo> aclInterfaceInfoList = (List<AclInterfaceInfo>) parameters
						.getParameters().get("aclInterfaceInfoList");

				Map<String, AclInterfaceInfo> delInterfaceMap = (Map<String, AclInterfaceInfo>) parameters
						.getParameters().get("delInterfaceMap");// 获得旧的接口

				this.addInterfaceList(aclInterfaceInfoList, delInterfaceMap, pe, para);
				// 
				pe.addCommand(pe.buildCommandOperate("end", cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
				pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
			}
			// [end] Acl Interface
		}
		// [end] 如果为添加

		// [start] 如果为修改
		else if (dealFlag.equals("modify")) {
			// [start] Time Range
			if (parameters.getParameters().containsKey("timerangeInfoList")) {

				// 开始设置命令
				pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd,
						cmdConfigEnd, null));

				List<TimeRangeInfo> timeRangeInfoList = (List<TimeRangeInfo>) parameters
						.getParameters().get("timerangeInfoList");

				this.modifyTimeRangeInfos(timeRangeInfoList, pe, para, (Device) item);

				// 
				pe.addCommand(pe.buildCommandOperate("end", cmdErrorStr + cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
				pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
			}
			// [end] Time Range

			// [start] Access List
			if (parameters.getParameters().containsKey("accessGroupInfoList")) {

				// 开始设置命令
				pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd,
						cmdConfigEnd, null));

				List<AccessGroupInfo> accessGroupInfoList = (List<AccessGroupInfo>) parameters
						.getParameters().get("accessGroupInfoList");

				this.modifyAccessGroupInfos(accessGroupInfoList, pe, para);
				// 
				pe.addCommand(pe.buildCommandOperate("end", cmdErrorStr + cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
				pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
			}
			// [end]

			// [start] Acl Interface
			if (parameters.getParameters().containsKey("aclInterfaceInfoList")) {
				// 开始设置命令
				pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd,
						cmdConfigEnd, null));

				List<AclInterfaceInfo> aclInterfaceInfoList = (List<AclInterfaceInfo>) parameters
						.getParameters().get("aclInterfaceInfoList");

				Map<String, AclInterfaceInfo> delInterfaceMap = (Map<String, AclInterfaceInfo>) parameters
						.getParameters().get("delInterfaceMap");// 获得旧的接口

				this.addInterfaceList(aclInterfaceInfoList, delInterfaceMap, pe, para);
				// 
				pe.addCommand(pe.buildCommandOperate("end", cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
				pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
						new HashMap[] { para }));
			}
			// [end] Acl Interface
		}
		// [end] 如果为修改

		// [start] 删除时间段 Time Range
		else if (dealFlag.equals(AclPlanTypeEnum.DeleteTimeRange.toString())
				&& parameters.getParameters().containsKey("timerangeInfoList")) {
			// 开始设置命令
			pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd, cmdConfigEnd,
					null));

			List<TimeRangeInfo> timeRangeInfoList = (List<TimeRangeInfo>) parameters
					.getParameters().get("timerangeInfoList");
			for (TimeRangeInfo timeRangeInfo : timeRangeInfoList) {
				if (!AclUtil.empty(timeRangeInfo.getName())) {
					// 时间段名称
					pe.addCommand(pe.buildCommandOperate(
							"no time-range " + timeRangeInfo.getName(), cmdErrorStr + cmdEnd,
							cmdEnd, null));
				}
			}

			// 更新ACL组中的时间段
			if (parameters.getParameters().containsKey("accessGroupInfoList")) {
				List<AccessGroupInfo> accessGroupInfoList = (List<AccessGroupInfo>) parameters
						.getParameters().get("accessGroupInfoList");
				this.modifyAccessGroupInfos(accessGroupInfoList, pe, para);
			}

			// 
			pe.addCommand(pe.buildCommandOperate("end", cmdErrorStr + cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
			pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));

		}
		// [end] 删除时间 Time Range

		// [start] 删除组 Access List
		else if (dealFlag.equals(AclPlanTypeEnum.DeleteAccessGroup.toString())
				&& parameters.getParameters().containsKey("accessGroupInfoList")) {
			// 开始设置命令
			pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd, cmdConfigEnd,
					null));

			List<AccessGroupInfo> accessGroupInfoList = (List<AccessGroupInfo>) parameters
					.getParameters().get("accessGroupInfoList");
			for (AccessGroupInfo accessGroupInfo : accessGroupInfoList) {
				this.deleteAccessGroupInfo(accessGroupInfo, pe, para, false);
			}
			// 更新与组相关的信息
			if (parameters.getParameters().containsKey("aclInterfaceInfoList")) {
				List<AclInterfaceInfo> aclInterfaceInfoList = (List<AclInterfaceInfo>) parameters
						.getParameters().get("aclInterfaceInfoList");
				for (AclInterfaceInfo aclInterfaceInfo : aclInterfaceInfoList) {
					deleteInterface(aclInterfaceInfo, pe, para);
				}
			}
			// 
			pe.addCommand(pe.buildCommandOperate("end", cmdErrorStr + cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
			pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
		}
		// [end] 删除组 Access List

		// [start] 删除接口 Acl Interface
		else if (parameters.getParameters().containsKey("aclInterfaceInfoList")) {
			List<AclInterfaceInfo> aclInterfaceInfoList = (List<AclInterfaceInfo>) parameters
					.getParameters().get("aclInterfaceInfoList");
			pe.addCommand(pe.buildCommandOperate("configure terminal", cmdConfigEnd, cmdConfigEnd,
					null));
			for (AclInterfaceInfo aclInterfaceInfo : aclInterfaceInfoList) {
				deleteInterface(aclInterfaceInfo, pe, para);
			}
			// 
			pe.addCommand(pe.buildCommandOperate("end", cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
			pe.addCommand(pe.buildCommandOperate("write", cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
		}
		// [end] 删除接口 Acl Interface

		try {
			Adapter adpater = new Adapter();
			Document doc = pe.getParameter();
			if (logger.isDebugEnabled()) {
				logger.debug(Dom4jUtil.generateXMLStringBuffer(doc, null));
			}

			String r = (String) adpater.execute(doc);
			doc = Dom4jUtil.createDOM4jDocument(r, false, null);

			String succ = doc.getRootElement().selectSingleNode("isSuccess").getText();
			String code = doc.getRootElement().selectSingleNode("resultCode").getText();
			String desc = doc.getRootElement().selectSingleNode("workOrderDesc").getText();

			result.setExecuted(succ.equals("true"));
			result.setSuccess(code.equals("true"));

			// 发布配置变更事件
			if (eventPublisher != null) {
				Map paras = new HashMap();
				paras.put("0", "Config-ACL-Device");
				paras.put("1", TaskAclUtil.getChildrenText((Element) doc.getRootElement()
						.selectSingleNode("sendCmds"), null));
				TaskAclUtil.publishEvent(eventPublisher, TaskAclDomain.DEVICE_CONFIG_CHANGED,
						device.getAdminIp(), paras);
			}

			if (!result.getSuccess()) {
				TaskUtil.buildBusinessException(//
						!result.getExecuted(), code.equals("retry"), !result.getSuccess(), desc);
			} else {
				result.setDescription(AdapterDomain.ADAPTER_EXECUTE_SUCCESS, new String[] {});
			}

			return result;
		} catch (BusinessException e) { // 业务异常抛出
			throw e;
		} catch (Exception e) {
			logger.error("TaskConfigAclDevice error.", e);
		}

		return null;
	}

	/**
	 * 下发时间段信息列表
	 * 
	 * @param timeRangeInfoList
	 *            时间段信息列表
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void addTimeRangeInfos(List<TimeRangeInfo> timeRangeInfoList, ParameterExecutor pe,
			HashMap para, Device device) {
		if (timeRangeInfoList != null && timeRangeInfoList.size() > 0) {
			for (TimeRangeInfo timeRangeInfo : timeRangeInfoList) {
				addTimeRangeInfo(timeRangeInfo, pe, para, device);
			}
		}
	}

	/**
	 * 下发时间段信息
	 * 
	 * @param timeRangeInfo
	 *            时间段信息
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void addTimeRangeInfo(TimeRangeInfo timeRangeInfo, ParameterExecutor pe, HashMap para,
			Device device) {
		if (timeRangeInfo != null && !AclUtil.empty(timeRangeInfo.getName())) {
			// 时间段名称
			pe.addCommand(pe.buildCommandOperate("no time-range " + timeRangeInfo.getName(),
					cmdEnd, cmdEnd, null));
			// 时间段名称
			pe.addCommand(pe.buildCommandOperate("time-range " + timeRangeInfo.getName(),
					cmdErrorStr + cmdEnd, cmdEnd, null));

			// 是否支持月份为January的模式
			boolean monthFlag = false;
			TaskTestAbsoluteTimeInfo taskTestAbsoluteTimeInfo = new TaskTestAbsoluteTimeInfo();
			try {
				ItemProcessResult result = taskTestAbsoluteTimeInfo.processItem(device,
						new PlanParameters());
				if (result != null) {
					monthFlag = true;
				}
			} catch (Exception ex) {

			}
			String absoluteString = "absolute";
			// 绝对时间信息
			if (timeRangeInfo.getAbsoluteStartDate() != null) {
				absoluteString += " start "
						+ AclConfigUtil.getAbsoluteDateString(timeRangeInfo.getAbsoluteStartDate(),
								monthFlag);
			}

			if (timeRangeInfo.getAbsoluteEndDate() != null) {
				absoluteString += " end "
						+ AclConfigUtil.getAbsoluteDateString(timeRangeInfo.getAbsoluteEndDate(),
								monthFlag);
			}
			if (!absoluteString.equals("absolute")) {
				pe.addCommand(pe.buildCommandOperate(absoluteString, cmdErrorStr + cmdEnd, cmdEnd,
						null));
				pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd, null));
				pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd, null));
			}

		
			// 时间列表信息
			//update by wangcj 对S2150G，S2126G型号设备继续特殊处理
			for (TimeInfo timeInfo : timeRangeInfo.getTimeInfoList()) {
			
				if("S2150G".equals(device.getDeviceModel().getName())||"S2126G".equals(device.getDeviceModel().getName())){
					String[] periodic=timeInfo.getPeriodic().split(" ");
					for(int i=0;i<periodic.length;i++){
						String timeInfoCmdStr = "periodic " + periodic[i]
						        + " " + timeInfo.getStartTime() + " to " + timeInfo.getEndTime();
						pe.addCommand(pe.buildCommandOperate(timeInfoCmdStr, cmdErrorStr
								+ countLineString(timeInfoCmdStr), countLineString(timeInfoCmdStr), null));
						pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd, null));
						pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd, null));
						
					}
				}else{
					String timeInfoCmdStr = "periodic " + timeInfo.getPeriodic().replace(",", " ")
					+ " " + timeInfo.getStartTime() + " to " + timeInfo.getEndTime();
					pe.addCommand(pe.buildCommandOperate(timeInfoCmdStr, cmdErrorStr
							+ countLineString(timeInfoCmdStr), countLineString(timeInfoCmdStr), null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd, null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd, null));
				}
			}
			// 退出时间段处理
			pe.addCommand(pe.buildCommandOperate("exit", cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
		}

	}

	/**
	 * 更新时间段信息
	 * 
	 * @param timeRangeInfo
	 *            时间段信息
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void modifyTimeRangeInfos(List<TimeRangeInfo> timeRangeInfoList, ParameterExecutor pe,
			HashMap para, Device device) {
		if (timeRangeInfoList != null && timeRangeInfoList.size() > 0) {
			for (TimeRangeInfo timeRangeInfo : timeRangeInfoList) {
				if (!AclUtil.empty(timeRangeInfo.getName())) {
					// 时间段名称
					// pe.addCommand(pe.buildCommandOperate("time-range " +
					// timeRangeInfo.getName(), cmdErrorStr + cmdEnd,
					// cmdEnd, null));
					// 时间段名称
					// pe.addCommand(pe.buildCommandOperate("no time-range " +
					// timeRangeInfo.getName(), cmdErrorStr
					// + cmdEnd, cmdEnd, null));
					// 添加时间段信息
					this.addTimeRangeInfo(timeRangeInfo, pe, para, device);
				}
			}
		}
	}

	/**
	 * 下发ACL组信息列表
	 * 
	 * @param accessGroupInfoList
	 *            ACL组信息列表
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void addAccessGroupInfos(List<AccessGroupInfo> accessGroupInfoList,
			ParameterExecutor pe, HashMap para) {
		if (accessGroupInfoList != null && accessGroupInfoList.size() > 0) {
			for (AccessGroupInfo accessGroupInfo : accessGroupInfoList) {
				deleteAccessGroupInfo(accessGroupInfo, pe, para, true);
				addAccessGroupInfo(accessGroupInfo, pe, para);
			}
		}

	}

	/**
	 * 下发ACL组信息列表
	 * 
	 * @param accessGroupInfoList
	 *            ACL组信息列表
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void modifyAccessGroupInfos(List<AccessGroupInfo> accessGroupInfoList,
			ParameterExecutor pe, HashMap para) {
		if (accessGroupInfoList != null && accessGroupInfoList.size() > 0) {
			for (AccessGroupInfo accessGroupInfo : accessGroupInfoList) {
				deleteAccessGroupInfo(accessGroupInfo, pe, para, false);
				addAccessGroupInfo(accessGroupInfo, pe, para);
			}
		}

	}

	/**
	 * 下发ACL组信息
	 * 
	 * @param accessGroupInfoList
	 *            ACL组信息
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void addAccessGroupInfo(AccessGroupInfo accessGroupInfo, ParameterExecutor pe,
			HashMap para) {
		if (accessGroupInfo != null && !AclUtil.empty(accessGroupInfo.getName())) {
			// 标准规则
			if (accessGroupInfo.getAclType().equals(AceTypeEnum.STANDARD.toString())) {
				// 下发组信息
				pe.addCommand(pe.buildCommandOperate("ip access-list standard "
						+ accessGroupInfo.getName(), cmdErrorStr + cmdEnd, cmdEnd, null));
				// [start]
				// 规则列表
				for (AceInfo aceInfo : accessGroupInfo.getAceInfoList()) {
					String aceCommandString = "";
					// 规则号
					if (!AclUtil.empty(aceInfo.getAceNum())) {
						aceCommandString += aceInfo.getAceNum() + " ";
					}
					// 动作
					if (!AclUtil.empty(aceInfo.getAceAction())) {
						aceCommandString += aceInfo.getAceAction() + " ";
					} else {
						continue;
					}

					// 匹配类型
					String matchType = aceInfo.getSourceMatchType();
					if (!AclUtil.empty(matchType)) {
						// 所有IP
						if (matchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (matchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getSourceAddr() + " ";
						}
						// 网段
						else {
							aceCommandString += aceInfo.getSourceAddr() + " "
									+ aceInfo.getSourceWildcard() + " ";
						}
					}

					// 时间段
					if (!AclUtil.empty(aceInfo.getTimeRangeName())) {
						aceCommandString += "time-range " + aceInfo.getTimeRangeName();
					}
					pe.addCommand(pe.buildCommandOperate(aceCommandString, cmdErrorStr + cmdEnd,
							cmdEnd, null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd,
							null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd,
							null));
				}
				// [end]
			} else if (accessGroupInfo.getAclType().equals(AceTypeEnum.EXTENDED.toString())) {
				// 下发组信息
				pe.addCommand(pe.buildCommandOperate("ip access-list extended "
						+ accessGroupInfo.getName(), cmdErrorStr + cmdEnd, cmdEnd, null));
				// [start] 扩展规则列表
				for (AceInfo aceInfo : accessGroupInfo.getAceInfoList()) {
					String aceCommandString = "";
					// 规则号
					if (!AclUtil.empty(aceInfo.getAceNum())) {
						aceCommandString += aceInfo.getAceNum() + " ";
					}
					// 动作
					if (!AclUtil.empty(aceInfo.getAceAction())) {
						aceCommandString += aceInfo.getAceAction() + " ";
					} else {
						continue;
					}

					// 协议
					if (!AclUtil.empty(aceInfo.getProtocolType())) {
						aceCommandString += aceInfo.getProtocolType() + " ";
					}

					// 源匹配类型
					String sourceMatchType = aceInfo.getSourceMatchType();
					if (!AclUtil.empty(sourceMatchType)) {
						// 所有IP
						if (sourceMatchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (sourceMatchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getSourceAddr() + " ";
						}
						// 网段
						else {
							aceCommandString += aceInfo.getSourceAddr() + " "
									+ aceInfo.getSourceWildcard() + " ";
						}
					}

					// 源端口
					if (!AclUtil.empty(aceInfo.getSourcePort())) {
						aceCommandString += "eq " + aceInfo.getSourcePort().toString() + " ";
					}

					// 目的匹配类型
					String desMatchType = aceInfo.getDesMatchType();
					if (!AclUtil.empty(desMatchType)) {
						// 所有IP
						if (desMatchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (desMatchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getDesAddr() + " ";
						}
						// 网段
						else {
							aceCommandString += aceInfo.getDesAddr() + " "
									+ aceInfo.getDesWildcard() + " ";
						}
					}

					// 目的端口
					if (!AclUtil.empty(aceInfo.getDesPort())) {
						aceCommandString += "eq " + aceInfo.getDesPort().toString() + " ";
					}

					// 时间段
					if (!AclUtil.empty(aceInfo.getTimeRangeName())) {
						aceCommandString += "time-range " + aceInfo.getTimeRangeName();
					}
					pe.addCommand(pe.buildCommandOperate(aceCommandString, cmdErrorStr
							+ countLineString(aceCommandString), countLineString(aceCommandString),
							null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd,
							null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd,
							null));
				}
				// [end]
			} else if (accessGroupInfo.getAclType().equals(AceTypeEnum.MAC.toString())) {
				// 下发组信息
				pe.addCommand(pe.buildCommandOperate("mac access-list extended "
						+ accessGroupInfo.getName(), cmdErrorStr + cmdEnd, cmdEnd, null));
				// [start] MAC扩展规则列表
				for (AceInfo aceInfo : accessGroupInfo.getAceInfoList()) {
					String aceCommandString = "";
					// 规则号
					if (!AclUtil.empty(aceInfo.getAceNum())) {
						aceCommandString += aceInfo.getAceNum() + " ";
					}
					// 动作
					if (!AclUtil.empty(aceInfo.getAceAction())) {
						aceCommandString += aceInfo.getAceAction() + " ";
					} else {
						continue;
					}

					// 源MAC匹配类型
					String sourceMacMatchType = aceInfo.getSourceMacMatchType();
					if (!AclUtil.empty(sourceMacMatchType)) {
						// 所有IP
						if (sourceMacMatchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (sourceMacMatchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getSourceMacAddr() + " ";
						}
					}

					// 目的MAC匹配类型
					String desMacMatchType = aceInfo.getDesMacMatchType();
					if (!AclUtil.empty(desMacMatchType)) {
						// 所有IP
						if (desMacMatchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (desMacMatchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getDesMacAddr() + " ";
						}
					}

					// 以太网协议
					if (!AclUtil.empty(aceInfo.getProtocolType())) {
						aceCommandString += aceInfo.getProtocolType() + " ";
					}

					// 时间段
					if (!AclUtil.empty(aceInfo.getTimeRangeName())) {
						aceCommandString += "time-range " + aceInfo.getTimeRangeName();
					}
					pe.addCommand(pe.buildCommandOperate(aceCommandString, cmdErrorStr + cmdEnd,
							cmdEnd, null));

					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd,
							null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd,
							null));
				}
				// [end]
			} else if (accessGroupInfo.getAclType().equals(AceTypeEnum.EXPERT.toString())) {
				// 下发组信息
				pe.addCommand(pe.buildCommandOperate("expert access-list extended "
						+ accessGroupInfo.getName(), cmdErrorStr + cmdEnd, cmdEnd, null));
				// [start] 专家扩展规则列表
				for (AceInfo aceInfo : accessGroupInfo.getAceInfoList()) {
					String aceCommandString = "";
					// 规则号
					if (!AclUtil.empty(aceInfo.getAceNum())) {
						aceCommandString += aceInfo.getAceNum() + " ";
					}
					// 动作
					if (!AclUtil.empty(aceInfo.getAceAction())) {
						aceCommandString += aceInfo.getAceAction() + " ";
					} else {
						continue;
					}

					// 协议
					if (!AclUtil.empty(aceInfo.getProtocolType())) {
						aceCommandString += aceInfo.getProtocolType() + " ";
					}

					// VLAN ID
					if (!AclUtil.empty(aceInfo.getVlanNum())) {
						aceCommandString += "VID " + aceInfo.getVlanNum() + " ";
					}

					// 源IP匹配类型
					String sourceMatchType = aceInfo.getSourceMatchType();
					if (!AclUtil.empty(sourceMatchType)) {
						// 所有IP
						if (sourceMatchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (sourceMatchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getSourceAddr() + " ";
						}
						// 网段
						else {
							aceCommandString += aceInfo.getSourceAddr() + " "
									+ aceInfo.getSourceWildcard() + " ";
						}
					}

					// 源MAC匹配类型
					String sourceMacMatchType = aceInfo.getSourceMacMatchType();
					if (!AclUtil.empty(sourceMacMatchType)) {
						// 所有IP
						if (sourceMacMatchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (sourceMacMatchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getSourceMacAddr() + " ";
						}
					}

					// 源端口
					if (!AclUtil.empty(aceInfo.getSourcePort())) {
						aceCommandString += "eq " + aceInfo.getSourcePort().toString() + " ";
					}

					// 目的IP匹配类型
					String desMatchType = aceInfo.getDesMatchType();
					if (!AclUtil.empty(desMatchType)) {
						// 所有IP
						if (desMatchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (desMatchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getDesAddr() + " ";
						}
						// 网段
						else {
							aceCommandString += aceInfo.getDesAddr() + " "
									+ aceInfo.getDesWildcard() + " ";
						}
					}

					// 目的MAC匹配类型
					String desMacMatchType = aceInfo.getDesMacMatchType();
					if (!AclUtil.empty(desMacMatchType)) {
						// 所有IP
						if (desMacMatchType.equals("any")) {
							aceCommandString += "any ";
						}
						// 主机
						else if (desMacMatchType.equals("host")) {
							aceCommandString += "host " + aceInfo.getDesMacAddr() + " ";
						}
					}

					// 目的端口
					if (!AclUtil.empty(aceInfo.getDesPort())) {
						aceCommandString += "eq " + aceInfo.getDesPort().toString() + " ";
					}

					// 时间段
					if (!AclUtil.empty(aceInfo.getTimeRangeName())) {
						aceCommandString += "time-range " + aceInfo.getTimeRangeName();
					}
					pe.addCommand(pe.buildCommandOperate(aceCommandString, cmdErrorStr
							+ countLineString(aceCommandString), countLineString(aceCommandString),
							null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd,
							null));
					pe.addCommand(pe.buildCommandOperate(cmdLine, cmdErrorStr + cmdEnd, cmdEnd,
							null));
				}
				// [end]
			}
			// 退出ACL组处理
			pe.addCommand(pe.buildCommandOperate("exit", cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
		}
	}

	/**
	 * 删除设备的组信息
	 * 
	 * @param accessGroupInfo
	 *            ACL组
	 * @param pe
	 * @param para
	 */
	@SuppressWarnings("unchecked")
	private void deleteAccessGroupInfo(AccessGroupInfo accessGroupInfo, ParameterExecutor pe,
			HashMap para, boolean errorFlag) {
		if (accessGroupInfo != null && !AclUtil.empty(accessGroupInfo.getName())) {
			String cmdString = cmdErrorStr + cmdEnd;
			if (errorFlag) {
				cmdString = cmdEnd;
			}
			// 标准规则
			if (accessGroupInfo.getAclType().equals(AceTypeEnum.STANDARD.toString())) {
				// 下发组信息
				pe.addCommand(pe.buildCommandOperate("no ip access-list standard "
						+ accessGroupInfo.getName(), cmdString, cmdEnd, null));
			} else if (accessGroupInfo.getAclType().equals(AceTypeEnum.EXTENDED.toString())) {
				// 下发组信息
				pe.addCommand(pe.buildCommandOperate("no ip access-list extended "
						+ accessGroupInfo.getName(), cmdString, cmdEnd, null));
			} else if (accessGroupInfo.getAclType().equals(AceTypeEnum.MAC.toString())) {
				// 下发组信息
				pe.addCommand(pe.buildCommandOperate("no mac access-list extended "
						+ accessGroupInfo.getName(), cmdString, cmdEnd, null));
			} else if (accessGroupInfo.getAclType().equals(AceTypeEnum.EXPERT.toString())) {
				// 下发组信息
				pe.addCommand(pe.buildCommandOperate("no expert access-list extended "
						+ accessGroupInfo.getName(), cmdString, cmdEnd, null));
			}
		}
	}

	/**
	 * 下发接口信息列表
	 * 
	 * @param interfaceInfoList
	 *            接口信息列表
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void addInterfaceList(List<AclInterfaceInfo> interfaceInfoList,
			Map<String, AclInterfaceInfo> delInterfaceMap, ParameterExecutor pe, HashMap para) {
		for (AclInterfaceInfo aclInterfaceInfo : interfaceInfoList) {
			AclInterfaceInfo temp = null;
			if (delInterfaceMap != null && delInterfaceMap.size() > 0) {
				temp = delInterfaceMap.get(aclInterfaceInfo.getIfName());
			}
			addInterface(aclInterfaceInfo, temp, pe, para);
		}
	}

	/**
	 * 下发接口信息
	 * 
	 * @param aclInterfaceInfo
	 *            接口信息
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void addInterface(AclInterfaceInfo aclInterfaceInfo, AclInterfaceInfo deleteInterface,
			ParameterExecutor pe, HashMap para) {
		if (aclInterfaceInfo != null && !AclUtil.empty(aclInterfaceInfo.getIfName())) {
			// 参数：关联接口名
			pe.addCommand(pe.buildCommandOperate("interface " + aclInterfaceInfo.getIfName(),
					cmdErrorStr + cmdEnd, cmdEnd, null));
			if (!AclUtil.empty(aclInterfaceInfo.getInAccessGroupName())) {
				// 删除旧的接口选择的组
				if (deleteInterface != null
						&& !AclUtil.empty(deleteInterface.getInAccessGroupName())) {
					pe.addCommand(pe
							.buildCommandOperate("no ip access-group "
									+ deleteInterface.getInAccessGroupName() + " in ", cmdEnd,
									cmdEnd, null));
				} else {
					pe.addCommand(pe.buildCommandOperate("no ip access-group "
							+ aclInterfaceInfo.getInAccessGroupName() + " in ", cmdEnd, cmdEnd,
							null));
				}
				pe.addCommand(pe.buildCommandOperate("ip access-group "
						+ aclInterfaceInfo.getInAccessGroupName() + " in ", cmdErrorStr + cmdEnd,
						cmdEnd, null));
			}

			if (!AclUtil.empty(aclInterfaceInfo.getOutAccessGroupName())) {
				if (deleteInterface != null
						&& !AclUtil.empty(deleteInterface.getOutAccessGroupName())) {
					pe.addCommand(pe.buildCommandOperate("no ip access-group "
							+ deleteInterface.getOutAccessGroupName() + " out ", cmdEnd, cmdEnd,
							null));
				} else {
					pe.addCommand(pe.buildCommandOperate("no ip access-group "
							+ aclInterfaceInfo.getOutAccessGroupName() + " out ", cmdEnd, cmdEnd,
							null));
				}
				pe.addCommand(pe.buildCommandOperate("ip access-group "
						+ aclInterfaceInfo.getOutAccessGroupName() + " out ", cmdErrorStr + cmdEnd,
						cmdEnd, null));
			}
			// 退出接口处理
			pe.addCommand(pe.buildCommandOperate("exit", cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
		}
	}

	/**
	 * 删除接口信息
	 * 
	 * @param aclInterfaceInfo
	 *            接口信息
	 * @param pe
	 *            参数执行器
	 * @param para
	 *            参数
	 */
	@SuppressWarnings("unchecked")
	private void deleteInterface(AclInterfaceInfo aclInterfaceInfo, ParameterExecutor pe,
			HashMap para) {
		if (aclInterfaceInfo != null && !AclUtil.empty(aclInterfaceInfo.getIfName())) {
			// 参数：关联接口名
			pe.addCommand(pe.buildCommandOperate("interface " + aclInterfaceInfo.getIfName(),
					cmdErrorStr + cmdEnd, cmdEnd, null));
			if (!AclUtil.empty(aclInterfaceInfo.getInAccessGroupName())) {
				pe.addCommand(pe.buildCommandOperate("no ip access-group "
						+ aclInterfaceInfo.getInAccessGroupName() + " in ", cmdErrorStr + cmdEnd,
						cmdEnd, null));
			}

			if (!AclUtil.empty(aclInterfaceInfo.getOutAccessGroupName())) {
				pe.addCommand(pe.buildCommandOperate("no ip access-group "
						+ aclInterfaceInfo.getOutAccessGroupName() + " out ", cmdErrorStr + cmdEnd,
						cmdEnd, null));
			}
			// 退出接口处理
			pe.addCommand(pe.buildCommandOperate("exit", cmdDoneFlag, cmdSuccFlag,
					new HashMap[] { para }));
		}
	}

	public EventPublisher getEventPublisher() {
		return eventPublisher;
	}

	public void setEventPublisher(EventPublisher eventPublisher) {
		this.eventPublisher = eventPublisher;
	}

	/**
	 * 判断设备软件版本是否是旧版
	 * 
	 * @param device
	 *            设备
	 * @return 设备软件版本是否是旧版
	 */
	private String getLineString(Device device) {
		// RGNOS 10.1.00(4), Release(18437)
		String ver = "";
		try {
			if (device != null) {
				ver = device.getSoftwareVersion();
				if (ver.indexOf("1.8") >= 0) {
					return "\r\n";
				}
			}
		} catch (Exception ex) {
			//
		}
		return "\n";
	}

	private String countLineString(String cmdStr) {
		String resultString = cmdEnd;
		if (this.getLineString(dealDevice).equals("\n")) {
			if (cmdStr.length() > 85) {
				int startPos = cmdStr.length() > 85 ? cmdStr.length() - 10 : 75;
				resultString = cmdStr.substring(startPos);
			} else if (cmdStr.length() > 50) {
				int startPos = cmdStr.length() > 60 ? cmdStr.length() - 10 : 50;
				resultString = cmdStr.substring(startPos);
			}
			
			if (cmdStr.length() > 50){
				StringBuffer sb = new StringBuffer();
				for(int i=0;i< resultString.length();i++){
					sb.append(resultString.charAt(i) + "\\s*") ;
				}
				resultString = sb.toString() + ".*" + cmdEnd;
			}
		}
		return resultString;
	}
}
